package pers.cl.dubbo.provider.service.impl;

import org.apache.dubbo.config.annotation.Argument;
import org.apache.dubbo.config.annotation.Method;
import org.apache.dubbo.config.annotation.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pers.cl.dubbo.api.model.User;
import pers.cl.dubbo.api.service.CallBackListener;
import pers.cl.dubbo.api.service.UserService;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author chenlei
 * @date 2020/1/9
 * @description
 **/
@Service(group = "user",validation = "true",
        methods = @Method(name = "addListener",
                arguments = {@Argument(index = 1,callback = true)}),callbacks = 1000)
public class UserServiceImpl implements UserService {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    public String sayHello(User user) {
        logger.info("dubbo调用成功"+user.getId()+user.getUserName());
        return "hello,userServieImpl";
    }

    /**
    *@author chenlei
    *@date 2020/1/13 15:38
    *@param
    *@return
    *@exception
    *@description  服务方异步执行
    **/
    @Override
    public CompletableFuture<String> async(User user) {
        logger.info(user.getId());
        return CompletableFuture.supplyAsync(()->{
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "async result";
        });
    }

    private final Map<String, CallBackListener> listenerMap = new ConcurrentHashMap<>();

    public UserServiceImpl(){
        Thread t = new Thread(new Runnable() {
            public void run() {
                while(true) {
                    try {
                        for(Map.Entry<String, CallBackListener> entry : listenerMap.entrySet()){
                            try {
                                entry.getValue().changed(changed(entry.getKey()));
                            } catch (Throwable t) {
                                listenerMap.remove(entry.getKey());
                            }
                        }
                        Thread.sleep(5000); // 定时触发变更通知
                    } catch (Throwable t) { // 防御容错
                        t.printStackTrace();
                    }
                }
            }
        });
        t.setDaemon(true);
        t.start();
    }

    @Override
    public void addListener(String key, CallBackListener listener) {
        listenerMap.put(key, listener);
        listener.changed(key);
    }

    private String changed(String key) {
        return "Changed: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
    }
}
